#include <jni.h>
#include <string>
#include <iostream>
#include "utils/LogUtils.h"
#include "utils/AES.h"
#include "utils/encryption.h"
#include "utils/md5.h"
#include <typeinfo>
#include <stdlib.h>
//#include "<android_log.h>"


// 公钥
static const char *APP_SIGNATURE = "308203833082026ba003020102020415080c6e300d06092a864886f70d01010b05003072310b300906035504061302383631123010060355040813094775616e67646f6e67310f300d06035504071306466f7368616e31193017060355040a13104e6f6c6f6e20546563686e6f6c6f6779310b3009060355040b13024954311630140603550403130d52696368617264205a68656e67301e170d3231303232303132303433335a170d3436303231343132303433335a3072310b300906035504061302383631123010060355040813094775616e67646f6e67310f300d06035504071306466f7368616e31193017060355040a13104e6f6c6f6e20546563686e6f6c6f6779310b3009060355040b13024954311630140603550403130d52696368617264205a68656e6730820122300d06092a864886f70d01010105000382010f003082010a0282010100bc7d5973ec0144d171575e7dbdbf138c5d367eb02f678414a49b50c939f265aa3b2c47bf256e3f25919820e061df6781100baab4586f5b7bd39f3e6f4b5c8557420b5bb9e444ce2f018e5fbd5d75531fa63edc8bde18d0fde5c2dd62c998e4d7d99032d8a9a0f15585cd94bb1ce3f2accd11ce071eaca67f003f565eb3291357dbe834d95fd9d530153ab99ae0619e95ed7d48e9bab9fff34949c6c04e138c01a44259f66b537ed8175d1836a76aebdf1f9ea5769d3cace71340732b6bdc9e14479a92ab1a4ff4f3c8018e02d5debd59543dfd953897ef0f5f584507f2f5ac1a8b8a8ae262d1aadfa53ef59b90a06a16271c91513726096797d8dfb5fc22fa770203010001a321301f301d0603551d0e04160414a6e356731a31a3b016887a739b1a9ef997925db5300d06092a864886f70d01010b0500038201010056fe292f5840e2699132fa76f5fd0d2db6c0ec0e8e8aaad468468a282c0bf04b773388216416b4a972acbe283cacaa0e92f8164d27f64def08a8d4cbeeb5f5c4dc5097e30dedd46bdfd66cb786134d20d51c6a59c8e1749a5155f5f0254c43578c824f6f6c7a345e1876e37e1fd3c9452c8fe2527c27a82b18034248b0f3a7a9d44f9f11b95de378c35ea6d504a53e4cca1a33ac8b2261c1ccfd637be8cbb4718b3f6ff93bea395217dd7a43f00b37e5defc8881ac6e9ed25e7351f80bc356d82b8351ab8ca49853c26927a0316c9cc3ce98d9e114b857cbeb42f136ff211b0489025fac929a16dd5563e2dd48a58d5f95b82125116a3bf383108b54fd5eceb4";

static const char *PACKAGE_NAME = "com.nolon.flange"; // 包名

void toast(JNIEnv *env, jobject context, jstring msg);

char *jstringTostring(JNIEnv *env, jstring jstr);

jstring CStr2Jstring(JNIEnv *env, const char *pat);

jstring getCurrTime(JNIEnv *env);

jstring genUUID(JNIEnv *env);

jstring genSn(JNIEnv *env, jstring date, jstring info, jstring aid, jstring uuid);

jstring genDeviceInfo(JNIEnv *env);

jstring getAndroidId(JNIEnv *env, jobject context);

// SharedPreference Get 方法
jboolean
getBooleanSharedPreferences(JNIEnv *env, jobject context, jstring jstr_key, jboolean jbool_default);

jstring getStringSharedPreferences(JNIEnv *env, jobject context, jstring jstr_key);

jint getIntSharedPreferences(JNIEnv *env, jobject context, jstring jstr_key);

jboolean verifySignatures(JNIEnv *env, jobject context);

// SharedPreference Set 方法
jstring
setStringSharedPreference(JNIEnv *env, jobject context, jstring jstr_key, jstring jstr_value);

jint
setIntSharedPreference(JNIEnv *env, jobject context, jstring jstr_key, jint jint_value);

jstring
setBooleanSharedPreference(JNIEnv *env, jobject context, jstring jstr_key, jboolean jbool_value);


jstring getStringSharedPreferences(JNIEnv *env, jobject context, jstring jstr_key) {
    jclass cls_PreferenceManager = env->FindClass("androidx/preference/PreferenceManager");
    if (cls_PreferenceManager == nullptr) {
        return env->NewStringUTF("PreferenceManager 类没找到！");
    }

    jmethodID method_get_default = env->GetStaticMethodID(cls_PreferenceManager,
                                                          "getDefaultSharedPreferences",
                                                          "(Landroid/content/Context;)Landroid/content/SharedPreferences;");
    if (method_get_default == nullptr) {
        return env->NewStringUTF("PreferenceManager 类没找到！");
    }

    jobject obj_sp = env->CallStaticObjectMethod(cls_PreferenceManager, method_get_default,
                                                 context);
    if (obj_sp == nullptr) {
        return env->NewStringUTF("SharePreference 对象没找到！");
    }
    jclass cls_SharedPreferences = env->FindClass("android/content/SharedPreferences");
    if (cls_SharedPreferences == nullptr) {
        return env->NewStringUTF("SharePreference 类没找到！");
    }
    jmethodID med_getString = env->GetMethodID(cls_SharedPreferences, "getString",
                                               "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
    if (med_getString == nullptr) {
        return env->NewStringUTF("SharePreference 类的getString方法没找到！");
    }
    jstring empty = CStr2Jstring(env, "");
    auto str_value = (jstring) env->CallObjectMethod(obj_sp, med_getString, jstr_key, empty);

    env->DeleteLocalRef(cls_SharedPreferences);
    env->DeleteLocalRef(cls_PreferenceManager);
    env->DeleteLocalRef(obj_sp);
    env->DeleteLocalRef(empty);
    return str_value;
}

jint getIntSharedPreferences(JNIEnv *env, jobject context, jstring jstr_key) {
    jclass cls_PreferenceManager = env->FindClass("androidx/preference/PreferenceManager");
    if (cls_PreferenceManager == nullptr) { //env->NewStringUTF("PreferenceManager 类没找到！")
        return -1;
    }

    jmethodID method_get_default = env->GetStaticMethodID(cls_PreferenceManager,
                                                          "getDefaultSharedPreferences",
                                                          "(Landroid/content/Context;)Landroid/content/SharedPreferences;");
    if (method_get_default == nullptr) { //env->NewStringUTF("PreferenceManager 类没找到！")
        return -1;
    }

    jobject obj_sp = env->CallStaticObjectMethod(cls_PreferenceManager, method_get_default,
                                                 context);
    if (obj_sp == nullptr) { //env->NewStringUTF("SharePreference 对象没找到！")
        return -1;
    }
    jclass cls_SharedPreferences = env->FindClass("android/content/SharedPreferences");
    if (cls_SharedPreferences == nullptr) { //env->NewStringUTF("SharePreference 类没找到！")
        return -1;
    }
    jmethodID med_getInt = env->GetMethodID(cls_SharedPreferences, "getInt",
                                            "(Ljava/lang/String;I)I");
    if (med_getInt == nullptr) { //env->NewStringUTF("SharePreference 类的getString方法没找到！")
        return -1;
    }
    jstring empty = CStr2Jstring(env, "");
    auto int_value = (jint) env->CallIntMethod(obj_sp, med_getInt, jstr_key, 0);

    env->DeleteLocalRef(cls_SharedPreferences);
    env->DeleteLocalRef(cls_PreferenceManager);
    env->DeleteLocalRef(obj_sp);
    env->DeleteLocalRef(empty);
    return int_value;
}


int getModeByName(const char *iModeName);

using namespace std;

jboolean verifySignatures(JNIEnv *env, jobject context) {
    //1、获取包名；
    jclass cls_ctx = env->GetObjectClass(context);
    jmethodID j_mid = env->GetMethodID(cls_ctx, "getPackageName", "()Ljava/lang/String;");
    jstring j_package_name = (jstring) env->CallObjectMethod(context, j_mid);

    //2、比对包名是否一样；
    const char *c_package_name = env->GetStringUTFChars(j_package_name, NULL);
    if (strcmp(c_package_name, PACKAGE_NAME) != 0) {
        return JNI_FALSE;
    }

    //3、获取签名
    //3.1、获取PackageManager
    j_mid = env->GetMethodID(cls_ctx, "getPackageManager", "()Landroid/content/pm/PackageManager;");
    jobject pack_manager = env->CallObjectMethod(context, j_mid);
    //3.2、获取PackageInfo
    cls_ctx = env->GetObjectClass(pack_manager);
    j_mid = env->GetMethodID(cls_ctx, "getPackageInfo",
                             "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
    jobject package_info = env->CallObjectMethod(pack_manager, j_mid, j_package_name, 64);
    //3.3、获取signatures 数组
    cls_ctx = env->GetObjectClass(package_info);
    jfieldID j_fid = env->GetFieldID(cls_ctx, "signatures", "[Landroid/content/pm/Signature;");
    jobjectArray signatures = (jobjectArray) env->GetObjectField(package_info, j_fid);
    //3.4、获取signatures[0]
    jobject signatures_first = env->GetObjectArrayElement(signatures, 0);
    //3.5、调用signatures[0].toCharsString()
    cls_ctx = env->GetObjectClass(signatures_first);
    j_mid = env->GetMethodID(cls_ctx, "toCharsString", "()Ljava/lang/String;");
    jstring j_signature_str = (jstring) env->CallObjectMethod(signatures_first, j_mid);
    const char *c_signature_str = env->GetStringUTFChars(j_signature_str, NULL);
    //4、比对签名是否一样；
    if (strcmp(c_signature_str, APP_SIGNATURE) != 0) {
        return JNI_FALSE;
    }
//    __android_log_print(ANDROID_LOG_ERROR, "this", "签名校验成功：%s", c_signature_str);
    //签名验证成功
//    is_verify = 1;
    env->DeleteLocalRef(cls_ctx);
    env->DeleteLocalRef(j_package_name);
    env->DeleteLocalRef(cls_ctx);
    env->DeleteLocalRef(pack_manager);
    env->DeleteLocalRef(package_info);
    env->DeleteLocalRef(signatures);
    env->DeleteLocalRef(signatures_first);
    env->DeleteLocalRef(j_signature_str);

    return JNI_TRUE;
}


jboolean getBooleanSharedPreferences(JNIEnv *env, jobject context, jstring jstr_key,
                                     jboolean jbool_default) {
    jclass cls_PreferenceManager = env->FindClass("androidx/preference/PreferenceManager");
    if (cls_PreferenceManager == nullptr) {
        return JNI_FALSE;//env->NewStringUTF("PreferenceManager 类没找到！");
    }

    jmethodID method_get_default = env->GetStaticMethodID(cls_PreferenceManager,
                                                          "getDefaultSharedPreferences",
                                                          "(Landroid/content/Context;)Landroid/content/SharedPreferences;");
    if (method_get_default == nullptr) {
        return JNI_FALSE;//env->NewStringUTF("PreferenceManager 类没找到！");
    }

    jobject obj_sp = env->CallStaticObjectMethod(cls_PreferenceManager, method_get_default,
                                                 context);
    if (obj_sp == nullptr) {
        return JNI_FALSE;//env->NewStringUTF("SharePreference 对象没找到！");
    }
    jclass cls_SharedPreferences = env->FindClass("android/content/SharedPreferences");
    if (cls_SharedPreferences == nullptr) {
        return JNI_FALSE;//env->NewStringUTF("SharePreference 类没找到！");
    }
    jmethodID med_getBool = env->GetMethodID(cls_SharedPreferences, "getBoolean",
                                             "(Ljava/lang/String;Z)Z");
    if (med_getBool == nullptr) {
        return JNI_FALSE;//env->NewStringUTF("SharePreference 类的getString方法没找到！");
    }
    auto bool_value = (jboolean) env->CallBooleanMethod(obj_sp, med_getBool, jstr_key,
                                                        jbool_default);

    env->DeleteLocalRef(cls_SharedPreferences);
    env->DeleteLocalRef(cls_PreferenceManager);
    env->DeleteLocalRef(obj_sp);
    return bool_value;
}


jstring
setStringSharedPreference(JNIEnv *env, jobject context, jstring jstr_key, jstring jstr_value) {
    jclass cls_pref_manager = env->FindClass("androidx/preference/PreferenceManager");
    if (cls_pref_manager == nullptr) {
        return env->NewStringUTF("PreferenceManager 类没找到！");
    }

    jmethodID method_get_default = env->GetStaticMethodID(cls_pref_manager,
                                                          "getDefaultSharedPreferences",
                                                          "(Landroid/content/Context;)Landroid/content/SharedPreferences;");
    if (method_get_default == nullptr) {
        return env->NewStringUTF("getDefaultSharedPreferences 方法没找到！");
    }
    // SharePreference Class
    jobject obj_sp = env->CallStaticObjectMethod(cls_pref_manager, method_get_default,
                                                 context);
    if (obj_sp == nullptr) {
        return env->NewStringUTF("SharePreference 对象没找到！");
    }

    jclass cls_SharedPreferences = env->FindClass("android/content/SharedPreferences");
    if (cls_SharedPreferences == nullptr) {
        return env->NewStringUTF("SharePreference 类没找到！");
    }
    jclass cls_Editor = env->FindClass("android/content/SharedPreferences$Editor");
    if (cls_Editor == nullptr) {
        return env->NewStringUTF("Editor 类没找到！");
    }
    jmethodID method_getEdit = env->GetMethodID(cls_SharedPreferences,
                                                "edit",
                                                "()Landroid/content/SharedPreferences$Editor;");
    // 注意，如果参数写成--> "()Landroid/content/SharedPreferences/Editor;");
    // 调试会失败，提示没有此静态方法！！！
    if (method_getEdit == nullptr) {
        return env->NewStringUTF("getEdit 方法没找到！");
    }
    // 注意，如果参数写成--> "()Landroid/content/SharedPreferences/Editor;");
    // 调试会失败，提示没有此静态方法！！！
    jobject obj_editor = env->CallObjectMethod(obj_sp, method_getEdit);
    if (obj_editor == nullptr) {
        return env->NewStringUTF("Editor 对象没找到！");
    }
    jmethodID method_putString = env->GetMethodID(cls_Editor,
                                                  "putString",
                                                  "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/SharedPreferences$Editor;");
    if (method_putString == nullptr) {
        return env->NewStringUTF("putString 方法没找到！");
    }
    jmethodID method_apply = env->GetMethodID(cls_Editor, "apply", "()V");
    if (method_apply == nullptr) {
        return env->NewStringUTF("apply方法没找到！");
    }
    env->CallObjectMethod(obj_editor, method_putString, jstr_key, jstr_value);
    env->CallVoidMethod(obj_editor, method_apply);
    return env->NewStringUTF("");
}

jint
setIntSharedPreference(JNIEnv *env, jobject context, jstring jstr_key, jint jint_value) {
    jclass cls_pref_manager = env->FindClass("androidx/preference/PreferenceManager");
    if (cls_pref_manager == nullptr) { //env->NewStringUTF("PreferenceManager 类没找到！")
        return -1;
    }

    jmethodID method_get_default = env->GetStaticMethodID(cls_pref_manager,
                                                          "getDefaultSharedPreferences",
                                                          "(Landroid/content/Context;)Landroid/content/SharedPreferences;");
    if (method_get_default == nullptr) {//env->NewStringUTF("getDefaultSharedPreferences 方法没找到！")
        return -2;
    }
    // SharePreference Class
    jobject obj_sp = env->CallStaticObjectMethod(cls_pref_manager, method_get_default,
                                                 context);
    if (obj_sp == nullptr) {//env->NewStringUTF("SharePreference 对象没找到！")
        return -3;
    }

    jclass cls_SharedPreferences = env->FindClass("android/content/SharedPreferences");
    if (cls_SharedPreferences == nullptr) { //env->NewStringUTF("SharePreference 类没找到！")
        return -4;
    }
    jclass cls_Editor = env->FindClass("android/content/SharedPreferences$Editor");
    if (cls_Editor == nullptr) { //   env->NewStringUTF("Editor 类没找到！")
        return -5;
    }
    jmethodID method_getEdit = env->GetMethodID(cls_SharedPreferences,
                                                "edit",
                                                "()Landroid/content/SharedPreferences$Editor;");
    // 注意，如果参数写成--> "()Landroid/content/SharedPreferences/Editor;");
    // 调试会失败，提示没有此静态方法！！！
    if (method_getEdit == nullptr) { //env->NewStringUTF("getEdit 方法没找到！")
        return -6;
    }
    // 注意，如果参数写成--> "()Landroid/content/SharedPreferences/Editor;");
    // 调试会失败，提示没有此静态方法！！！
    jobject obj_editor = env->CallObjectMethod(obj_sp, method_getEdit);
    if (obj_editor == nullptr) { // env->NewStringUTF("Editor 对象没找到！")
        return -7;
    }
    jmethodID method_putInt = env->GetMethodID(cls_Editor,
                                               "putInt",
                                               "(Ljava/lang/String;I)Landroid/content/SharedPreferences$Editor;");
    if (method_putInt == nullptr) { //env->NewStringUTF("putString 方法没找到！")
        return -8;
    }
    jmethodID method_apply = env->GetMethodID(cls_Editor, "apply", "()V");
    if (method_apply == nullptr) { //env->NewStringUTF("apply方法没找到！")
        return -9;
    }
    env->CallObjectMethod(obj_editor, method_putInt, jstr_key, jint_value);
    env->CallVoidMethod(obj_editor, method_apply);
    return 1;
}


jstring
setBooleanSharedPreference(JNIEnv *env, jobject context, jstring jstr_key, jboolean jbool_value) {
    jclass cls_pref_manager = env->FindClass("androidx/preference/PreferenceManager");
    if (cls_pref_manager == nullptr) {
        return env->NewStringUTF("PreferenceManager 类没找到！");
    }

    jmethodID method_get_default = env->GetStaticMethodID(cls_pref_manager,
                                                          "getDefaultSharedPreferences",
                                                          "(Landroid/content/Context;)Landroid/content/SharedPreferences;");
    if (method_get_default == nullptr) {
        return env->NewStringUTF("getDefaultSharedPreferences 方法没找到！");
    }
    // SharePreference Class
    jobject obj_sp = env->CallStaticObjectMethod(cls_pref_manager, method_get_default,
                                                 context);
    if (obj_sp == nullptr) {
        return env->NewStringUTF("SharePreference 对象没找到！");
    }

    jclass cls_SharedPreferences = env->FindClass("android/content/SharedPreferences");
    if (cls_SharedPreferences == nullptr) {
        return env->NewStringUTF("SharePreference 类没找到！");
    }
    jclass cls_Editor = env->FindClass("android/content/SharedPreferences$Editor");
    if (cls_Editor == nullptr) {
        return env->NewStringUTF("Editor 类没找到！");
    }
    jmethodID method_getEdit = env->GetMethodID(cls_SharedPreferences,
                                                "edit",
                                                "()Landroid/content/SharedPreferences$Editor;");
    if (method_getEdit == nullptr) {
        return env->NewStringUTF("getEdit 方法没找到！");
    }
    // 注意，如果参数写成--> "()Landroid/content/SharedPreferences/Editor;");
    // 调试会失败，提示没有此静态方法！！！
    jobject obj_editor = env->CallObjectMethod(obj_sp, method_getEdit);
    if (obj_editor == nullptr) {
        return env->NewStringUTF("Editor 对象没找到！");
    }
    jmethodID method_putBoolean = env->GetMethodID(cls_Editor,
                                                   "putBoolean",
                                                   "(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;");
    if (method_putBoolean == nullptr) {
        return env->NewStringUTF("putBoolean方法没找到！");
    }
    jmethodID method_apply = env->GetMethodID(cls_Editor, "apply", "()V");
    if (method_apply == nullptr) {
        return env->NewStringUTF("apply方法没找到！");
    }
    env->CallBooleanMethod(obj_editor, method_putBoolean, jstr_key, jbool_value);
    env->CallVoidMethod(obj_editor, method_apply);
    return env->NewStringUTF("");
}

jstring getCurrTime(JNIEnv *env) {
    // 生成时间
    jclass cls_System = env->FindClass("java/lang/System");
    jmethodID method_currentTime = env->GetStaticMethodID(cls_System, "currentTimeMillis", "()J");
    jlong obj_currentTime = env->CallStaticLongMethod(cls_System, method_currentTime);
    char buf[64];
    sprintf(buf, "%ld", (long) obj_currentTime);
    jstring str_value_date = env->NewStringUTF(buf);
    env->DeleteLocalRef(cls_System);
    return str_value_date;
}

jstring genUUID(JNIEnv *env) {
    jclass cls_UUID = env->FindClass("java/util/UUID");
    jmethodID method_GenId = env->GetStaticMethodID(cls_UUID, "randomUUID", "()Ljava/util/UUID;");
    jmethodID method_toString = env->GetMethodID(cls_UUID, "toString", "()Ljava/lang/String;");
    jobject obj_uuid = env->CallStaticObjectMethod(cls_UUID, method_GenId);
    auto str_value_uuid = (jstring) env->CallObjectMethod(obj_uuid, method_toString);
    env->DeleteLocalRef(cls_UUID);
    env->DeleteLocalRef(obj_uuid);
    return str_value_uuid;
}

jstring genDeviceInfo(JNIEnv *env) {
    // 生成手机Info
    jclass cls_build = env->FindClass("android/os/Build");

    jfieldID field_ID = env->GetStaticFieldID(cls_build, "ID", "Ljava/lang/String;");
    jstring string_ID = (jstring) env->GetStaticObjectField(cls_build, field_ID);

    jfieldID field_DEVICE = env->GetStaticFieldID(cls_build, "DEVICE", "Ljava/lang/String;");
    jstring string_DEVICE = (jstring) env->GetStaticObjectField(cls_build, field_DEVICE);

    jfieldID field_BOARD = env->GetStaticFieldID(cls_build, "BOARD", "Ljava/lang/String;");
    jstring string_BOARD = (jstring) env->GetStaticObjectField(cls_build, field_BOARD);

    jfieldID field_BRAND = env->GetStaticFieldID(cls_build, "BRAND", "Ljava/lang/String;");
    jstring string_BRAND = (jstring) env->GetStaticObjectField(cls_build, field_BRAND);

    jfieldID field_HARDWARE = env->GetStaticFieldID(cls_build, "HARDWARE", "Ljava/lang/String;");
    jstring string_HARDWARE = (jstring) env->GetStaticObjectField(cls_build, field_HARDWARE);

    jfieldID field_PRODUCT = env->GetStaticFieldID(cls_build, "PRODUCT", "Ljava/lang/String;");
    jstring string_PRODUCT = (jstring) env->GetStaticObjectField(cls_build, field_PRODUCT);

    jfieldID field_MODEL = env->GetStaticFieldID(cls_build, "MODEL", "Ljava/lang/String;");
    jstring string_MODEL = (jstring) env->GetStaticObjectField(cls_build, field_MODEL);

    std::string compose_info;
    compose_info.append(jstringTostring(env, string_ID));
    compose_info.append("|");
    compose_info.append(jstringTostring(env, string_DEVICE));
    compose_info.append("|");
    compose_info.append(jstringTostring(env, string_BOARD));
    compose_info.append("|");
    compose_info.append(jstringTostring(env, string_BRAND));
    compose_info.append("|");
    compose_info.append(jstringTostring(env, string_HARDWARE));
    compose_info.append("|");
    compose_info.append(jstringTostring(env, string_PRODUCT));
    compose_info.append("|");
    compose_info.append(jstringTostring(env, string_MODEL));
    jstring str_value_info = env->NewStringUTF(compose_info.c_str());
    env->DeleteLocalRef(cls_build);
    env->DeleteLocalRef(string_ID);
    env->DeleteLocalRef(string_DEVICE);
    env->DeleteLocalRef(string_BOARD);
    env->DeleteLocalRef(string_BRAND);
    env->DeleteLocalRef(string_HARDWARE);
    env->DeleteLocalRef(string_PRODUCT);
    env->DeleteLocalRef(string_MODEL);

    return str_value_info;
}

/**
 * 获取Android Id
 * @param env
 * @param context
 * @return Android Id
 */
jstring getAndroidId(JNIEnv *env, jobject context) {
    jclass cls_secure = env->FindClass("android/provider/Settings$Secure");
    jmethodID method_getString = env->GetStaticMethodID(cls_secure, "getString",
                                                        "(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;");

    jclass cls_content_resolver = env->FindClass("android/content/ContentResolver");
    jclass cls_context = env->FindClass("android/content/Context");
    jmethodID method_get_content_resolver = env->GetMethodID(cls_context, "getContentResolver",
                                                             "()Landroid/content/ContentResolver;");
    jobject obj_content_resolver = env->CallObjectMethod(context, method_get_content_resolver);
    jfieldID field_android_id = env->GetStaticFieldID(cls_secure, "ANDROID_ID",
                                                      "Ljava/lang/String;");
    auto const_str_android_id = (jstring) env->GetStaticObjectField(cls_secure, field_android_id);
    auto str_android_id = (jstring) env->CallStaticObjectMethod(cls_secure, method_getString,
                                                                obj_content_resolver,
                                                                const_str_android_id);
    env->DeleteLocalRef(cls_secure);
    env->DeleteLocalRef(cls_content_resolver);
    env->DeleteLocalRef(cls_context);
    env->DeleteLocalRef(obj_content_resolver);
    return str_android_id;
}

jstring genSn(JNIEnv *env, jstring date, jstring info, jstring aid, jstring uuid) {
    return env->NewStringUTF("");
}

char *jstringTostring(JNIEnv *env, jstring jstr) {
    char *rtn = NULL;
    jclass clsstring = env->FindClass("java/lang/String");
    jstring strencode = env->NewStringUTF("utf-8");
    jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
    jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
    jsize alen = env->GetArrayLength(barr);
    jbyte *ba = env->GetByteArrayElements(barr, JNI_FALSE);
    if (alen > 0) {
        rtn = (char *) malloc(alen + 1);
        memcpy(rtn, ba, alen);
        rtn[alen] = 0;
    }
    env->ReleaseByteArrayElements(barr, ba, 0);
    return rtn;
}

jstring CStr2Jstring(JNIEnv *env, const char *pat) {
    //定义java String类 strClass
    jclass strClass = (env)->FindClass("java/lang/String");
    //获取java String类方法String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
    jmethodID ctorID = (env)->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
    //建立byte数组
    jbyteArray bytes = (env)->NewByteArray((jsize) strlen(pat));
    //将char* 转换为byte数组
    (env)->SetByteArrayRegion(bytes, 0, (jsize) strlen(pat), (jbyte *) pat);
    //设置String, 保存语言类型,用于byte数组转换至String时的参数
    jstring encoding = (env)->NewStringUTF("utf-8");
    //将byte数组转换为java String,并输出
    return (jstring) (env)->NewObject(strClass, ctorID, bytes, encoding);
}

int getModeByName(const char *iModeName) {
    if (strcmp("CFB", iModeName) == 0) {
        return AES::CFB;
    } else if (strcmp("ECB", iModeName) == 0) {
        return AES::ECB;
    } else {
        return AES::CBC;
    }
}

/**
 * Can't toast on a thread that has not called Looper.prepare()!!!
 * @param env
 * @param context
 * @param msg
 */
void toast(JNIEnv *env, jobject context, jstring msg) {
    jclass cls_t = (env)->FindClass("android/widget/Toast");
    if (!cls_t) return;
    jmethodID method_make = env->GetStaticMethodID(cls_t, "makeText",
                                                   "(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;");
    jobject obj_t = env->CallStaticObjectMethod(cls_t, method_make, context, msg, 0);
    if (!obj_t) return;
    jmethodID method_show = env->GetMethodID(cls_t, "show", "()V");
    env->CallVoidMethod(obj_t, method_show);
}